<template>
  <div class="form-designer">
    <div class="designer-container">
      <!-- 左侧字段列表 -->
      <div class="fields-panel">
        <div class="panel-header">
          <span class="panel-title">表单字段</span>
          <el-button type="primary" link @click="showAddField">
            <el-icon><Plus /></el-icon>
            添加字段
          </el-button>
        </div>
        <div class="fields-list">
          <el-scrollbar :height="props.contentHeight">
            <el-empty v-if="!localFields.length" description="暂无字段" />
            <draggable v-else v-model="localFields" item-key="id" handle=".drag-handle">
              <template #item="{ element, index }">
                <div class="field-item" :class="{ active: fieldForm.id === element.id }">
                  <div class="field-header">
                    <div class="field-info">
                      <!-- <i :class="'iconfont',index < 2? drag-handle:''">&#xe7dc;</i> -->
                      <i :class="['iconfont',index > 1 ? 'drag-handle':'']">&#xe7dc;</i>

                      <span class="field-index">{{ index + 1 }}.</span>
                      <span class="field-label">{{ element.label }}</span>
                    </div>
                    <div class="field-actions">
                      <!-- <i class="iconfont delete-btn" >&#xe74b;</i>
                      <i class="iconfont icon-bianji" >&#xe69b;</i> -->
                      <el-icon class="iconfont delete-btn" v-if="index > 1" @click.stop="handleDeleteField(index)"><Delete /></el-icon>
                      <el-icon class="iconfont edit-btn" @click="editField(element)"><Edit /></el-icon>
                    </div>
                  </div>
                </div>
              </template>
            </draggable>
          </el-scrollbar>
        </div>
      </div>

      <!-- 右侧预览 -->
      <div class="preview-panel">
        <div class="panel-header">
          <span class="panel-title">表单预览</span>
        </div>
        <div class="preview-content">
          <el-scrollbar :height="props.contentHeight">
            <el-empty v-if="!localFields.length" description="请添加表单字段" />
            <FormRenderer v-else :fields="localFields" :model-value="{}" label-width="auto" />
          </el-scrollbar>
        </div>
      </div>
    </div>

    <!-- 字段配置对话框 -->
    <el-dialog v-model="fieldDialog" :title="fieldForm.id ? '编辑字段' : '添加字段'" width="500px" @close="handleDialogClose">
      <el-form ref="fieldFormRef" :model="fieldForm" :rules="fieldRules" label-width="80px">
        <el-form-item label="字段类型" prop="type">
          <el-select v-model="fieldForm.type" placeholder="请选择字段类型">
            <el-option v-for="type in fieldTypes" :key="type.value" :label="type.label" :value="type.value" />
          </el-select>
        </el-form-item>

        <el-form-item label="字段名称" prop="label">
          <el-input v-model="fieldForm.label" placeholder="请输入字段名称" />
        </el-form-item>

        <!-- 单行文本输入框增加正则校验选择 -->
        <el-form-item label="正则校验" v-if="fieldForm.type == 'input'" prop="check">
          <el-radio-group v-model="fieldForm.check">
            <el-radio v-for="option in checkList" :key="option.value" :label="option.value">
              <span class="radio-label">{{option.label}}</span>
            </el-radio>
          </el-radio-group>
        </el-form-item>

        <el-form-item label="字数限制" v-if="fieldForm.type == 'input'">
          <el-switch v-model="fieldForm.openRestrict" />
        </el-form-item>  

        <el-form-item label="最大字数" v-if="fieldForm.openRestrict && fieldForm.type == 'input'">
          <el-input-number v-model="fieldForm.maxLength" :min="1" :step="1" />
        </el-form-item>

        <!-- 数字输入框增加最大数字和精度设置 -->
        <el-form-item label="最大数字" v-if="fieldForm.type == 'numberInput'">
          <el-input-number v-model="fieldForm.maxNumber" :min="1" :step="1" />
        </el-form-item>

        <el-form-item label="精度设置" v-if="fieldForm.type == 'numberInput'">
          <el-input-number v-model="fieldForm.precision" :min="0" :max="4" :step="1" />
        </el-form-item>

        <el-form-item label="是否必填">
          <el-switch v-model="fieldForm.required" />
        </el-form-item>

        <el-form-item label="隐私信息">
          <el-switch v-model="fieldForm.privacy" />
        </el-form-item>

        <el-form-item label="说明">
          <el-input v-model="fieldForm.description" placeholder="请输入字段说明" />
        </el-form-item>

        <el-form-item label="宽度">
          <el-input-number v-model="fieldForm.width" :min="1" :max="100" :step="1" @change="handleChange" />
        </el-form-item>
        <!-- 选项配置（用于select、multiSelect和classify） -->
        <template v-if="['classify', 'select', 'multiSelect'].includes(fieldForm.type)">
          <el-form-item label="选项" prop="option">
            <div style="width: 100%;">
              <div>
                <el-button type="primary" link @click="addOption">
                  <el-icon><Plus /></el-icon>
                  添加选项
                </el-button>
              </div>
              <div v-for="(option, index) in fieldForm.options" :key="index" class="option-item">
                <el-input v-model="option.label" placeholder="选项文本" />
                  <el-button type="danger" link @click="removeOption(index)">
                  <el-icon style="font-size: 16px;"><Delete /></el-icon>
                </el-button>
              </div>
            </div>
          </el-form-item>
        </template>
      </el-form>

      <template #footer>
        <span class="dialog-footer">
          <el-button @click="fieldDialog = false">取消</el-button>
          <el-button type="primary" @click="handleFieldSubmit">确认</el-button>
        </span>
      </template>
    </el-dialog>
  </div>
</template>

<script setup>
import { ref, defineProps, defineEmits, watch } from 'vue'
import { Delete, Plus, Edit } from '@element-plus/icons-vue'
import { pinyin } from 'pinyin-pro'
import FormRenderer from './FormRenderer.vue'
import draggable from 'vuedraggable'
import { ElMessageBox } from 'element-plus'

const props = defineProps({
  modelValue: {
    type: Array,
    default: () => []
  },
  contentHeight: {
    type: Number,
    default: 500
  }
})
const emits = defineEmits(['update:modelValue'])

const localFields = ref([...props.modelValue])
console.log("localFields",localFields.value);

// 字段类型配置
const fieldTypes = [
  { label: '分类设置', value: 'classify' },
  { label: '单行文本', value: 'input' },
  { label: '多行文本', value: 'textarea' },
  { label: '数字输入', value: 'numberInput' },
  { label: '下拉单选', value: 'select' },
  { label: '下拉多选', value: 'multiSelect' },
  // { label: '文字说明', value: 'text' },
  { label: '日期选择', value: 'date' },
  { label: '文件上传', value: 'upload' }
]

//正则校验字段
const checkList = ref([
  { label: '电话号码', value: 'phone' },
  { label: '邮箱', value: 'mailbox' },
  { label: '身份证号', value: 'numberId' },
  { label: '邮政编码', value: 'postalCode' },
  { label: '无', value: 'null' },
])

// 字段添加
const fieldDialog = ref(false)
const fieldFormRef = ref(null)
//选项检验
const validateOptions = (rule, value, callback) => { // 接收 callback 参数
  if (fieldForm.value.options.length === 0) {
    callback(new Error('请至少添加一个选项'));
  } else {
    const hasEmptyLabel = fieldForm.value.options.some(option => !option.label.trim());
    if (hasEmptyLabel) {
      callback(new Error('选项文本不能为空'));
    } else {
      callback(); // 验证通过
    }
  }
}
const fieldRules = {
  type: [{ required: true, message: '请选择字段类型', trigger: 'change' }], 
  label: [{ required: true, message: '请输入字段名称', trigger: 'blur' }],
  option: [{ validator: validateOptions, trigger: 'blur' }],
}

const defaultFieldForm = {
  type: '',
  label: '',
  description: '',
  check: '',
  required: false,
  privacy: false,
  width: 100,
  openRestrict: false,
  maxLength: 50,
  maxNumber: 100,
  precision: 1,
  options: []
}
const fieldForm = ref(Object.assign({}, defaultFieldForm))

// 字段英文名生成
const generateFieldName = label => {
  const pinyinStr = pinyin(label, { toneType: 'none' }).split(' ').join('_')
  const randomStr = Math.random().toString(36).substring(2, 6)
  return `${pinyinStr}_${randomStr}`
}

// 字段添加
const showAddField = () => {
  fieldDialog.value = true
}

// 字段编辑
const editField = field => {
  fieldForm.value = structuredClone(field)
  const booleanFields = ['required', 'privacy', 'openRestrict'];

  booleanFields.forEach(field => {
    if (fieldForm.value[field] === "true" || fieldForm.value[field] === "false") {
      fieldForm.value[field] = fieldForm.value[field] === "true";
    }
  });
  
  fieldDialog.value = true
}

// 字段提交
const handleFieldSubmit = async () => {
  if (!fieldFormRef.value) return
  //如果未开启字数限制，清空最大长度
  if(fieldForm.value.openRestrict == false) {
    fieldForm.value.maxLength = 0
  }
  console.log("fieldForm.value",fieldForm.value);
  
  try {
    const valid = await fieldFormRef.value.validate()
    if (!valid) return

    const fieldData = {
      ...fieldForm.value,
      name: generateFieldName(fieldForm.value.label)
    }

    if (fieldForm.value.id) {
      const index = localFields.value.findIndex(f => f.id === fieldForm.value.id)
      if (index !== -1) {
        localFields.value[index] = { ...fieldData, id: fieldForm.value.id }
      }
    } else {
      localFields.value.push({
        ...fieldData,
        id: Date.now().toString()
      })
    }
    fieldDialog.value = false
    fieldForm.value.options = [];
  } catch (error) {
    console.error('表单验证失败:', error)
  }
}

// 字段删除
const handleDeleteField = index => {
  ElMessageBox.confirm('确定要删除该字段吗？', '提示', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    type: 'warning'
  })
  .then(() => localFields.value.splice(index, 1))
  .catch(() => {})
}

// 选项添加
const addOption = () => {
  fieldForm.value.options.push({ 
    label: '', 
    value: Date.now().toString() 
  })
}

// 选项删除
const removeOption = index => {
  console.log(fieldForm.value.options);
  fieldForm.value.options.splice(index, 1)
}

const handleDialogClose = () => {
  fieldFormRef.value.clearValidate()
  fieldForm.value = structuredClone(defaultFieldForm)
}

//更新数据
watch(() => props.modelValue, (newValue) => {
  // 使用 deep copy 避免直接修改父组件传入的数据
  localFields.value = structuredClone(newValue);
}, { deep: true });
// 对外暴露的方法
defineExpose({
  save: () => {
    emits('update:modelValue', localFields.value)
  }
})

</script>

<style lang="scss" scoped>
.form-designer {
  height: 600px;

  .designer-container {
    display: flex;
    gap: 20px;
    height: 100%;
    border-radius: 4px;

    .panel-header {
      display: flex;
      justify-content: space-between;
      align-items: center;
      padding: 16px;
      background: var(--el-bg-color);
      border-bottom: 1px solid var(--el-border-color-light);
      border-radius: 4px 4px 0 0;

      .panel-title {
        font-size: 14px;
        font-weight: 500;
        color: var(--el-text-color-primary);
      }
    }

    .fields-panel {
      width: 300px;
      background: var(--el-bg-color);
      border: 1px solid var(--el-border-color-light);
      border-radius: 4px;
      display: flex;
      flex-direction: column;

      .fields-list {
        flex: 1;
        padding: 16px;

        :deep(.el-scrollbar__wrap) {
          height: 100%;
        }

        .el-scrollbar {
          height: 100%;
        }

        .field-item {
          padding: 8px 12px;
          margin-bottom: 8px;
          background: var(--el-bg-color);
          border: 1px solid var(--el-border-color-lighter);
          border-radius: 4px;
          transition: all 0.2s;

          &:hover {
            background: var(--el-fill-color-light);

            .field-actions {
              opacity: 1 !important;
            }
          }

          &.active {
            border-color: var(--el-color-primary);
            background: var(--el-color-primary-light-9);
          }

          .field-header {
            display: flex;
            align-items: center;
            justify-content: space-between;

            .field-info {
              display: flex;
              align-items: center;
              gap: 8px;
              flex: 1;

              .drag-handle {
                cursor: move;
                color: $mainColor;
                font-size: 12px;

                &:hover {
                  color: var(--el-text-color-primary);
                }
              }

              .field-index {
                color: var(--el-text-color-secondary);
                font-size: 12px;
                min-width: 18px;
              }

              .field-label {
                font-size: 12px;
                color: var(--el-text-color-primary);
                @include textEllipsis(12px, 1);
              }
            }

            .field-actions {
              display: flex;
              align-items: center;
              gap: 8px;
              opacity: 0;
              transition: opacity 0.2s;

              i {
                font-size: 14px;
                cursor: pointer;

                &.delete-btn {
                  color: #f56c6c;
                }

                &.edit-btn {
                  color: #409eff;
                }
              }
            }
          }
        }
      }
    }

    .preview-panel {
      flex: 1;
      background: var(--el-bg-color);
      border: 1px solid var(--el-border-color-light);
      border-radius: 4px;
      display: flex;
      flex-direction: column;

      .preview-content {
        flex: 1;
        padding: 20px;

        :deep(.el-scrollbar__wrap) {
          height: 100%;
        }

        .el-scrollbar {
          height: 100%;
        }
      }
    }

    
  }
  .tips{
    font-size: 12px;
    color: $mainColor;
    line-height: 14px;
  }
  .option-item {
    display: flex;
    gap: 8px;
    margin-bottom: 8px;
  }
  .radio-label{
    margin-right: 10px;
  }
}
</style>
